package com.atguigu.crowd.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.comm.ResponseMessage;
import com.aliyun.oss.model.PutObjectResult;
import com.atguigu.crowd.constant.CrowdConstant;

public class CrowdUtil {

	public static ResultEntity<String> sendMessage(String param, String phone, String host, String path, String appcode,
			String sign, String skin) {
		String error = "";
		String urlSend = host + path + "?param=" + param + "&phone=" + phone + "&sign=" + sign + "&skin=" + skin; // 【5】拼接请求链接
		try {
			URL url = new URL(urlSend);
			HttpURLConnection httpURLCon = (HttpURLConnection) url.openConnection();
			httpURLCon.setRequestProperty("Authorization", "APPCODE " + appcode);// 格式Authorization:APPCODE (中间是英文空格)
			int httpCode = httpURLCon.getResponseCode();
			if (httpCode == 200) {
				String json = read(httpURLCon.getInputStream());
				System.out.println("正常请求计费(其他均不计费)");
				System.out.println("获取返回的json:");
				System.out.print(json);
				return ResultEntity.successWithData(json);
			} else {
				Map<String, List<String>> map = httpURLCon.getHeaderFields();
				error = map.get("X-Ca-Error-Message").get(0);
				if (httpCode == 400 && error.equals("Invalid AppCode `not exists`")) {
					System.out.println("AppCode错误 ");
				} else if (httpCode == 400 && error.equals("Invalid Url")) {
					System.out.println("请求的 Method、Path 或者环境错误");
				} else if (httpCode == 400 && error.equals("Invalid Param Location")) {
					System.out.println("参数错误");
				} else if (httpCode == 403 && error.equals("Unauthorized")) {
					System.out.println("服务未被授权（或URL和Path不正确）");
				} else if (httpCode == 403 && error.equals("Quota Exhausted")) {
					System.out.println("套餐包次数用完 ");
				} else {
					System.out.println("参数名错误 或 其他错误");
					System.out.println(error);
				}
			}

		} catch (MalformedURLException e) {
			System.out.println("URL格式错误");
			error = "URL格式错误";
		} catch (UnknownHostException e) {
			System.out.println("URL地址错误");
			error = "URL地址错误";
		} catch (Exception e) {
			// 打开注释查看详细报错异常信息
			error = "其他错误";
			e.printStackTrace();
		}

		return ResultEntity.failed(error);
	}

	/*
	 * 读取返回结果
	 */
	private static String read(InputStream is) throws IOException {
		StringBuffer sb = new StringBuffer();
		BufferedReader br = new BufferedReader(new InputStreamReader(is));
		String line = null;
		while ((line = br.readLine()) != null) {
			line = new String(line.getBytes(), "utf-8");
			sb.append(line);
		}
		br.close();
		return sb.toString();
	}

	/**
	 * 对明文字符串进行 MD5 加密
	 * 
	 * @param source 传入的明文字符串
	 * @return 加密结果
	 */
	public static String md5(String source) {
		// 1.判断 source 是否有效
		if (source == null || source.length() == 0) {
			// 2.如果不是有效的字符串抛出异常
			throw new RuntimeException(CrowdConstant.MESSAGE_STRING_INVALIDATE);
		}
		try {
			// 3.获取 MessageDigest 对象
			String algorithm = "md5";
			MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
			// 4.获取明文字符串对应的字节数组
			byte[] input = source.getBytes();
			// 5.执行加密
			byte[] output = messageDigest.digest(input);
			// 6.创建 BigInteger 对象
			int signum = 1;
			BigInteger bigInteger = new BigInteger(signum, output);
			// 7.按照 16 进制将 bigInteger 的值转换为字符串
			int radix = 16;
			String encoded = bigInteger.toString(radix).toUpperCase();
			return encoded;
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 判断请求是否是ajax请求
	 * 
	 * @param request
	 * @return
	 */
	public static boolean isAjaxRequest(HttpServletRequest request) {
		String accept = request.getHeader("Accept");
		String xRequestHeader = request.getHeader("X-Requested-With");
		return ((accept != null && accept.contains("application/json"))
				|| (xRequestHeader != null && xRequestHeader.equals("XMLHttpRequest")));
	}

	/**
	 * 专门负责上传文件到 OSS 服务器的工具方法
	 * 
	 * @param endpoint        OSS 参数
	 * @param accessKeyId     OSS 参数
	 * @param accessKeySecret OSS 参数
	 * @param inputStream     要上传的文件的输入流
	 * @param bucketName      OSS 参数
	 * @param bucketDomain    OSS 参数
	 * @param originalName    要上传的文件的原始文件名
	 * @return 包含上传结果以及上传的文件在 OSS 上的访问路径
	 */
	public static ResultEntity<String> uploadFileToOss(String endpoint, String accessKeyId, String accessKeySecret,

			InputStream inputStream, String bucketName, String bucketDomain, String originalName) {
		// 创建 OSSClient 实例。
		OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
		// 生成上传文件的目录
		String folderName ="crowd" + "/" + new SimpleDateFormat("yyyyMMdd").format(new Date());
		// 生成上传文件在 OSS 服务器上保存时的文件名
		// 原始文件名：beautfulgirl.jpg
		// 生成文件名：wer234234efwer235346457dfswet346235.jpg
		// 使用 UUID 生成文件主体名称
		String fileMainName = UUID.randomUUID().toString().replace("-", "");
		// 从原始文件名中获取文件扩展名
		String extensionName = originalName.substring(originalName.lastIndexOf("."));
		// 使用目录、文件主体名称、文件扩展名称拼接得到对象名称
		String objectName = folderName + "/" + fileMainName + extensionName;
		try {
			// 调用 OSS 客户端对象的方法上传文件并获取响应结果数据
			PutObjectResult putObjectResult = ossClient.putObject(bucketName, objectName, inputStream);
			// 从响应结果中获取具体响应消息
			ResponseMessage responseMessage = putObjectResult.getResponse();
			// 根据响应状态码判断请求是否成功
			if (responseMessage == null) {
				// 拼接访问刚刚上传的文件的路径
				String ossFileAccessPath = bucketDomain + "/" + objectName;
				// 当前方法返回成功
				return ResultEntity.successWithData(ossFileAccessPath);
			} else {
				// 获取响应状态码
				int statusCode = responseMessage.getStatusCode();
				// 如果请求没有成功，获取错误消息
				String errorMessage = responseMessage.getErrorResponseAsString();
				// 当前方法返回失败
				return ResultEntity.failed(" 当前响应状态码 =" + statusCode + " 错误消息=" + errorMessage);
			}
		} catch (Exception e) {
			e.printStackTrace();
			// 当前方法返回失败
			return ResultEntity.failed(e.getMessage());
		} finally {
			if (ossClient != null) {
				// 关闭 OSSClient。
				ossClient.shutdown();
			}
		}
	}

	
}
